package com.eastfair.venuebooking.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.eastfair.annotation.annotation.base.BaseControllerInfo;
import com.eastfair.annotation.annotation.log.SysLog;
import com.eastfair.annotation.annotation.security.PreAuth;
import com.eastfair.boot.controller.SuperController;
import com.eastfair.boot.request.PageParams;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.core.base.R;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.echo.core.EchoService;
import com.eastfair.venuebooking.demand.CustomerMainGroup;
import com.eastfair.venuebooking.dto.*;
import com.eastfair.venuebooking.entity.CustomerMain;
import com.eastfair.venuebooking.enumeration.BelongRecordOperateTypeEnum;
import com.eastfair.venuebooking.enums.CustomerStateEnum;
import com.eastfair.venuebooking.service.CustomerMainService;
import com.eastfair.venuebooking.vo.ContractHistogramVO;
import com.eastfair.venuebooking.vo.CustomerMainVO;
import com.eastfair.venuebooking.vo.CustomerStatisticsVO;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.constraints.NotEmpty;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * <p>
 * 前端控制器
 * 客户表
 * </p>
 *
 * @author linan
 * @date 2022 -06-08
 */
@Slf4j
@Validated
@RestController
@RequestMapping("/customerMain")
@Api(value = "CustomerMain", tags = "客户表")
@PreAuth(replace = "venuebooking:customerMain:")
public class CustomerMainController extends SuperController<CustomerMainService, Long, CustomerMain, CustomerMainPageQuery, CustomerMainSaveDTO, CustomerMainUpdateDTO> {

    @Resource
    private EchoService echoService;

    @Resource
    private CustomerMainService customerMainService;

    @Override
    public void handlerResult(IPage<CustomerMain> page) {
        // 想让返回值实现自动回显，请将此行代码打开
        // echoService.action(page);
    }

    /**
     * Excel导入后的操作
     *
     * @param list
     */
    @Override
    public R<Boolean> handlerImport(List<Map<String, String>> list) {
        List<CustomerMain> customerMainList = list
                .stream()
                .map((map) -> CustomerMain.builder().build())
                .collect(Collectors.toList());
        return R.success(baseService.saveBatch(customerMainList));
    }


    /**
     * 处理参数
     *
     * @param params 分页参数
     */
    @Override
    public void handlerQueryParams(PageParams<CustomerMainPageQuery> params) {
        CustomerMainPageQuery pageQuery = params.getModel();
        //分页处理
        if (ContextUtil.getProjectId() != null) {
            pageQuery.setProjectId(ContextUtil.getProjectId());
        }
    }

    @Override
    public R<CustomerMain> handlerUpdate(CustomerMainUpdateDTO model) {
        // 更新时将客户同步状态置为待同步
        model.setCmsSync(BusinessConstant.NO);
        return R.successDef();
    }

    /**
     * 分页查询客户列表.
     *
     * @param pageParam the page param
     * @return the r
     */
    @PostMapping("/page/customerMain")
    @BaseControllerInfo(voGroup = {CustomerMainGroup.QueryCustomerMain.class})
    public R<IPage<CustomerMainVO>> queryCustomerMain(@RequestBody PageParams<CustomerMainQuery> pageParam) {
        log.info("pageCustomerMain - 分页查询客户列表 pageParam={}", pageParam);

        IPage<CustomerMainVO> page = customerMainService.listCustomerMainVOs(pageParam);
        return success(page);
    }

    /**
     * 分页查询正常客户列表.
     *
     * @param pageParam the page param
     * @return the r
     */
    @PostMapping("/page/normal/customerMain")
    @BaseControllerInfo(voGroup = {CustomerMainGroup.QueryCustomerMain.class})
    public R<IPage<CustomerMainVO>> queryNormalCustomerMain(@RequestBody PageParams<CustomerMainQuery> pageParam) {
        log.info("pageCustomerMain - 分页查询正常客户列表 pageParam={}", pageParam);

        CustomerMainQuery model = pageParam.getModel();
        model.setState(CustomerStateEnum.NORMAL.getCode());
        IPage<CustomerMainVO> page = customerMainService.listCustomerMainVOs(pageParam);
        return success(page);
    }

    /**
     * 分页查询我的客户列表.
     *
     * @param pageParam the page param
     * @return the r
     */
    @PostMapping("/page/me/customerMain")
    @BaseControllerInfo(voGroup = {CustomerMainGroup.QueryCustomerMain.class})
    public R<IPage<CustomerMainVO>> queryMyCustomerMain(@RequestBody PageParams<CustomerMainQuery> pageParam) {
        log.info("pageMyCustomerMain - 分页查询我的客户列表 pageParam={}", pageParam);

        CustomerMainQuery model = pageParam.getModel();
        model.setBelongTo(ContextUtil.getUserId());
        model.setState(CustomerStateEnum.NORMAL.getCode());
        IPage<CustomerMainVO> page = customerMainService.listCustomerMainVOs(pageParam);
        return success(page);
    }

    /**
     * 分页查询重点客户列表.
     *
     * @param pageParam the page param
     * @return the r
     */
    @PostMapping("/page/star/customerMain")
    @BaseControllerInfo(voGroup = {CustomerMainGroup.QueryCustomerMain.class})
    public R<IPage<CustomerMainVO>> queryStarCustomerMain(@RequestBody PageParams<CustomerMainQuery> pageParam) {
        log.info("pageStarCustomerMain - 分页查询重点客户列表 pageParam={}", pageParam);

        CustomerMainQuery model = pageParam.getModel();
        model.setStarUserId(ContextUtil.getUserId());
        model.setState(CustomerStateEnum.NORMAL.getCode());
        IPage<CustomerMainVO> page = customerMainService.listCustomerMainVOs(pageParam);
        return success(page);
    }

    /**
     * 分页查询公海客户列表.
     *
     * @param pageParam the page param
     * @return the r
     */
    @PostMapping("/page/public/customerMain")
    @BaseControllerInfo(voGroup = {CustomerMainGroup.QueryCustomerMain.class})
    public R<IPage<CustomerMainVO>> queryPublicCustomerMain(@RequestBody PageParams<CustomerMainQuery> pageParam) {
        log.info("pagePublicCustomerMain - 分页查询公海客户列表 pageParam={}", pageParam);

        CustomerMainQuery model = pageParam.getModel();
        model.setState(CustomerStateEnum.PUBLIC.getCode());
        IPage<CustomerMainVO> page = customerMainService.listCustomerMainVOs(pageParam);
        return success(page);
    }

    /**
     * 分页查询静默客户列表.
     *
     * @param pageParam the page param
     * @return the r
     */
    @Deprecated
    @PostMapping("/page/silence/customerMain")
    @BaseControllerInfo(voGroup = {CustomerMainGroup.QueryCustomerMain.class})
    public R<IPage<CustomerMainVO>> querySilenceCustomerMain(@RequestBody PageParams<CustomerMainQuery> pageParam) {
        log.info("pageSilenceCustomerMain - 分页查询静默客户列表 pageParam={}", pageParam);

        CustomerMainQuery model = pageParam.getModel();
        model.setState(CustomerStateEnum.SILENCE.getCode());
        IPage<CustomerMainVO> page = customerMainService.listCustomerMainVOs(pageParam);
        return success(page);
    }

    /**
     * 获取客户详情.
     *
     * @param id the id
     * @return the r
     */
    @GetMapping("/get/{id}")
    public R<CustomerMainVO> getById(@PathVariable("id") Long id) {
        log.info("getCustomerMain - 获取客户详情, id={}", id);

        CustomerMainVO customerMainVO = customerMainService.getCustomerMainVOById(id);
        return R.successDef(customerMainVO);
    }

    /**
     * 保存客户.
     *
     * @param saveDTO the save dto
     * @return the r
     */
    @SysLog("新增客户")
    @PostMapping("/save")
    public R<Boolean> saveCustomerMain(@RequestBody @Validated(CustomerMainDTO.Save.class)
                                       CustomerMainContactSaveDTO saveDTO) {
        log.info("saveCustomerMain - 保存客户 saveDTO={}", saveDTO);

        return R.successDef(customerMainService.saveCustomerMain(saveDTO));
    }

    /**
     * 移除客户.
     *
     * @param ids the ids
     * @return the r
     */
    @SysLog("删除客户")
    @PostMapping("/remove")
    public R<Boolean> deleteCustomerMain(@RequestBody @NotEmpty(message = "客户id列表不可为空") List<Long> ids) {
        log.info("remove - 移除客户 ids={}", ids);

        return R.successDef(customerMainService.removeCustomerMainByIds(ids));
    }

    /**
     * 移入公海.
     *
     * @param publicDTO the update dto list
     * @return the r
     */
    @SysLog("客户移入公海")
    @PostMapping("/in/public")
    public R<Boolean> updateInPublic(@RequestBody @Validated({CustomerMainDTO.Public.class})
                                     CustomerMainPublicDTO publicDTO) {
        log.info("moveCustomerMainPublic - 移入公海, publicDTO={}", publicDTO);
        return R.successDef(customerMainService.updatePublic(publicDTO));
    }

    /**
     * 分配客户.
     *
     * @param assignDTO the assign dto
     * @return the r
     */
    @SysLog("分配客户")
    @PostMapping("/assign")
    public R<Boolean> updateAssign(@RequestBody @Validated({CustomerMainDTO.Assign.class})
                                   CustomerMainAssignDTO assignDTO) {
        log.info("assign - 分配客户, assignDTO={}", assignDTO);
        assignDTO.setOperateType(BelongRecordOperateTypeEnum.ASSIGN);
        return R.successDef(customerMainService.updateBelongTo(assignDTO));
    }

    /**
     * 领取客户.
     *
     * @param list the assign dto
     * @return the r
     */
    @SysLog("领取客户")
    @PostMapping("/take")
    public R<Boolean> updateTake(@RequestBody
                                 @NotEmpty(message = "领取列表不可为空")
                                 List<CustomerMainAssignDTO> list) {
        log.info("take - 领取客户, list={}", list);

        list.forEach(assignDTO -> assignDTO.setOperateType(BelongRecordOperateTypeEnum.TAKE));
        return R.successDef(customerMainService.updateBelongTo(list));
    }

    /**
     * 将客户设为静默.
     *
     * @param updateDTO the update dto
     * @return the r
     */
    @Deprecated
    @SysLog("静默客户")
    @PostMapping("/silence")
    public R<Boolean> updateSilence(@RequestBody @Validated(CustomerMainDTO.Silence.class) CustomerMainDTO updateDTO) {
        log.info("silence - 将客户设为静默, updateDTO={}", updateDTO);
        return R.successDef(customerMainService.updateSilence(updateDTO));
    }

    /**
     * 关注/取关客户.
     *
     * @return the r
     */
    @SysLog("关注/取关客户")
    @PostMapping("/star")
    public R<Boolean> updateStartCustomerMain(@RequestBody @Validated({CustomerMainDTO.Star.class})
                                              CustomerMainStartDTO startDTO) {
        log.info("startCustomerMain - 关注/取关客户, updateDTO={}", startDTO);

        return R.successDef(customerMainService.updateStartCustomerMain(startDTO));
    }

    /**
     * 更新客户crm同步状态为已同步.
     *
     * @param ids the ids
     * @return the r
     */
    @PostMapping("/update/crm/sync")
    public R<Boolean> updateCrmHasSync(@RequestBody List<Long> ids) {
        log.info("updateCrmHasSync - 更新客户crm同步状态为已同步, ids={}", ids);
        return R.successDef(customerMainService.updateCrmHasSync(ids));
    }

    /**
     * 查询客户的统计信息.
     *
     * @param id the id
     * @return the customer statistics
     */
    @GetMapping("/get/statistics/{id}")
    public R<CustomerStatisticsVO> getCustomerStatistics(@PathVariable("id") Long id) {
        log.info("queryCustomerStatistics - 查询客户的统计信息, id={}", id);

        return R.successDef(customerMainService.getCustomerStatistics(id));
    }

    /**
     * 查询成交量统计柱状图.
     *
     * @param id the id
     * @return the r
     */
    @GetMapping("/contract/histogram/{id}")
    public R<List<ContractHistogramVO>> queryContractHistogram(@PathVariable("id") Long id) {
        log.info("queryContractHistogram - 查询成交量统计柱状图, id={}", id);

        return R.successDef(customerMainService.countEveryYearContractAmountById(id));
    }

    /**
     * 查询待同步到cms的客户.
     *
     * @return the r
     */
    @GetMapping("/cms/sync")
    public R<List<CustomerMainVO>> queryForSyncCms() {
        log.info("queryForSyncCms - 查询待同步到cms的客户");
        return R.successDef(customerMainService.listWaitCmsSync());
    }
}
